package api

import (
	"context"
	"gin-template/config"
	"gin-template/global"
	"gin-template/model"
	"gin-template/utils"
	"log"
	"net/http"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

func Register(c *gin.Context) {
	var user model.User
	if err := c.ShouldBindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"message": "参数错误",
		})
		return
	}

	pwd, err := utils.BcryptPassword(user.Password)

	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err,
		})
		return
	}

	user.Password = pwd

	if err := global.MysqlDB.Create(&user).Error; err != nil {
		log.Println("User creation failure", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"message": err,
		})
		return
	}

	c.JSON(200, gin.H{
		"message": "注册成功",
	})
}

func Login(c *gin.Context) {
	var input struct {
		Username string `json:"username"`
		Password string `json:"password"`
	}

	if err := c.ShouldBindBodyWithJSON(&input); err != nil {
		log.Println("input error", err)
		c.JSON(http.StatusBadRequest, gin.H{
			"message": "参数错误",
		})
		return
	}

	var user model.User

	if err := global.MysqlDB.Where("username = ?", input.Username).First(&user).Error; err != nil {
		log.Println("search error", err)
		c.JSON(http.StatusUnauthorized, gin.H{
			"error": err,
		})
		return
	}

	if !utils.CheckPwd(user.Password, input.Password) {
		log.Println("password error")
		c.JSON(http.StatusNonAuthoritativeInfo, gin.H{
			"message": "密码错误",
		})
		return
	}

	token, err := utils.GenerateJWT(user.Username)

	// 单会话登录
	if config.AppConfig.App.SingleSessionLogin {
		duration, err := time.ParseDuration(config.AppConfig.Jwt.ExpiresTime)
		if err != nil {
			log.Println("parse duration error", err)
			c.JSON(http.StatusInternalServerError, gin.H{
				"message": "参数错误",
			})
		}
		global.RedisDB.Set(context.Background(), user.Username, token, duration)
	}

	if err != nil {
		log.Println("generate token error", err)
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err,
		})
		return
	}

	c.JSON(200, gin.H{
		"token": token,
	})
}

func LoginedTest(c *gin.Context) {
	token := c.GetHeader("Authorization")
	if token == "" {
		c.JSON(http.StatusUnauthorized, gin.H{
			"message": "未登录",
		})
		return
	}

	token = strings.TrimPrefix(token, "Bearer ")

	c.JSON(200, gin.H{
		"token":   token,
		"message": "登录成功",
	})
}
